import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { createVNode } from 'vue';
import { UserModule } from '@/store/modules/user'

export class Request {
    public static axiosInstance: AxiosInstance;

    // constructor() {
    //     // 创建axios实例
    //     this.axiosInstance = axios.create({timeout: 1000 * 12});
    //     // 初始化拦截器
    //     this.initInterceptors();
    // }

    public static init() {

        // 创建axios实例
        this.axiosInstance = axios.create({
            baseURL: process.env.VUE_APP_BASE_URL, // url = base url + request url
            timeout: 6000

            // withCredentials: true // send cookies when cross-domain requests
        });

        // 初始化拦截器
        this.initInterceptors();

        return axios;
    }

    // 为了让http.ts中获取初始化好的axios实例
    // public getInterceptors() {
    //     return this.axiosInstance;
    // }

    // 初始化拦截器
    public static initInterceptors() {

        // 设置post请求头
        this.axiosInstance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

        /**
         * 请求拦截器
         * 每次请求前，如果存在token则在请求头中携带token
         */
        this.axiosInstance.interceptors.request.use(
            (config: AxiosRequestConfig) => {
                if (UserModule.token) {
                    config.headers!.Authorization = UserModule.token;
                }

                return config;
            },
            (error: any) => {
                console.log(error);
            }
        );

        // 响应拦截器
        this.axiosInstance.interceptors.response.use(

            // 请求成功
            (response: AxiosResponse) => {
                if (response.status === 200) {

                    // return Promise.resolve(response.data);
                    // message.success(res.msg);
                    return response.data;
                }

                Request.errorHandle(response);

                // return Promise.reject(response.data);
                return response.data;

            },

            // 请求失败
            (error: any) => {
                const { response } = error;
                if (response) {

                    // 请求已发出，但是不在2xx的范围
                    Request.errorHandle(response);
                    return Promise.reject(response.data);
                }

                // 处理断网的情况
                // eg:请求超时或断网时，更新state的network状态
                // network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
                // 关于断网组件中的刷新重新获取数据，会在断网组件中说明
                message.error('网络连接异常,请稍后再试!');
            });
    }

    /**
     * http握手错误
     * @param res 响应回调,根据不同响应进行不同操作
     */
    private static errorHandle(res: any) {

        // 状态码判断
        switch (res.status) {
            case 401:
                if (res.data.code === 10013 || res.data.code === 10014) {
                    Modal.confirm({
                        content: '你已登出，可以取消继续留在该页面，或者重新登录',
                        icon: createVNode(ExclamationCircleOutlined),
                        okText: '重新登录',
                        onOk() {
                            UserModule.ResetToken()
                            location.reload() // 防止vue-router有bug
                        },
                        cancelText: '继续停留该页面',
                        onCancel() {
                            Modal.destroyAll();
                        }
                    });
                }
                break;
            case 403:
                break;
            case 404:
                message.error('请求的资源不存在');
                break;
            case 422:
                message.error(res.data.msg);
                break;
            default:
                message.error('连接错误');
        }
    }
}
